from PySide6.QtCore import QAbstractTableModel, QModelIndex, QSortFilterProxyModel, Qt
from PySide6.QtGui import QColor, QFont
from PySide6.QtWidgets import QMessageBox
from typing import List, Optional, Set

from src.backend.data_manager import DataManager


class TableModel(QAbstractTableModel):
    """表格模型 - 与数据管理器集成"""
    
    def __init__(self, data_manager):
        super().__init__()
        self._data_manager = data_manager
        self._proxy_model: Optional[QSortFilterProxyModel] = None
        self._column_range: List[int] = []  # 显示的列范围
        
    def set_proxy_model(self, proxy_model: QSortFilterProxyModel):
        """设置代理模型"""
        self._proxy_model = proxy_model
        
    def rowCount(self, parent=QModelIndex()):
        """获取行数"""
        if parent.isValid():
            return 0
        return self._data_manager.get_row_count()
    
    def columnCount(self, parent=QModelIndex()):
        """获取列数"""
        if parent.isValid():
            return 0
        if self._column_range:
            return len(self._column_range)
        return self._data_manager.get_column_count()
    
    def data(self, index, role=Qt.DisplayRole):
        """获取数据"""
        if not index.isValid():
            return None
            
        row = index.row()
        col = index.column()
        
        # 获取实际的数据列索引
        if self._column_range and col < len(self._column_range):
            actual_col = self._column_range[col]
        else:
            column_order = self._data_manager.get_column_order()
            if col < len(column_order):
                actual_col = column_order[col]
            else:
                actual_col = col
            
        if role == Qt.DisplayRole or role == Qt.EditRole:
            return self._data_manager.get_cell_data(row, actual_col)
            
        elif role == Qt.BackgroundRole:
            # 根据修改状态设置背景色
            if self._data_manager.is_row_disabled(row):
                return QColor(240, 240, 240)  # 浅灰色 - 禁用的行
            elif self._data_manager.is_cell_modified(row, actual_col):
                return QColor(255, 255, 200)  # 浅黄色 - 修改的单元格
            elif self._data_manager.is_row_added(row):
                return QColor(200, 255, 200)  # 浅绿色 - 新增的行
            elif self._data_manager.is_row_deleted(row):
                return QColor(255, 200, 200)  # 浅红色 - 删除的行
            else:
                return None
                
        elif role == Qt.FontRole:
            # 为修改的单元格设置粗体字体
            if self._data_manager.is_cell_modified(row, actual_col):
                font = QFont()
                font.setBold(True)
                return font
            return None
            
        return None
    
    def setData(self, index, value, role=Qt.EditRole):
        """设置数据"""
        if not index.isValid() or role != Qt.EditRole:
            return False
            
        row = index.row()
        col = index.column()
        
        # 获取实际的数据列索引
        if self._column_range and col < len(self._column_range):
            actual_col = self._column_range[col]
        else:
            column_order = self._data_manager.get_column_order()
            if col < len(column_order):
                actual_col = column_order[col]
            else:
                actual_col = col
            
        # 检查值是否真的改变了
        current_value = self._data_manager.get_cell_data(row, actual_col)
        if current_value == value:
            return True
            
        # 设置新值
        if self._data_manager.set_cell_data(row, actual_col, str(value)):
            # 通知视图数据已改变
            self.dataChanged.emit(index, index)
            return True
            
        return False
    
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        """获取表头数据"""
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            # 获取列标题
            data, headers = self._data_manager.get_data()
            
            if self._column_range and section < len(self._column_range):
                actual_col = self._column_range[section]
                if actual_col < len(headers):
                    return headers[actual_col]
                else:
                    return f"列 {actual_col}"
            else:
                column_order = self._data_manager.get_column_order()
                if section < len(column_order):
                    actual_col = column_order[section]
                    if actual_col < len(headers):
                        return headers[actual_col]
                    else:
                        return f"列 {actual_col}"
                else:
                    return f"列 {section}"
            
        elif orientation == Qt.Vertical and role == Qt.DisplayRole:
            return str(section + 1)
            
        elif orientation == Qt.Horizontal and role == Qt.BackgroundRole:
            # 为标记的列设置背景色
            if self._column_range and section < len(self._column_range):
                actual_col = self._column_range[section]
                if actual_col in self._data_manager.get_marked_columns():
                    return QColor(255, 255, 180)  # 浅黄色背景
            return None
            
        elif orientation == Qt.Horizontal and role == Qt.FontRole:
            # 为标记的列设置粗体字体
            if self._column_range and section < len(self._column_range):
                actual_col = self._column_range[section]
                if actual_col in self._data_manager.get_marked_columns():
                    font = QFont()
                    font.setBold(True)
                    return font
            return None
            
        return None
    
    def flags(self, index):
        """获取单元格标志"""
        if not index.isValid():
            return Qt.NoItemFlags
        
        row = index.row()
        
        # 禁用的行不可编辑，但可以选择
        if self._data_manager.is_row_disabled(row):
            return Qt.ItemIsEnabled | Qt.ItemIsSelectable  # 允许选择，不允许编辑
        
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
    
    def refresh_data(self):
        """刷新数据"""
        # 使用更精确的数据变更通知
        if self.rowCount() > 0 and self.columnCount() > 0:
            # 通知所有数据已改变
            top_left = self.index(0, 0)
            bottom_right = self.index(self.rowCount() - 1, self.columnCount() - 1)
            if top_left.isValid() and bottom_right.isValid():
                self.dataChanged.emit(top_left, bottom_right)
        else:
            # 如果数据为空，使用重置模型
            self.beginResetModel()
            self.endResetModel()
            
        # 发出布局变更信号，确保视图正确更新
        self.layoutChanged.emit()

    def get_column_order(self) -> List[int]:
        """获取列顺序"""
        return self._data_manager.get_column_order()
    
    def set_column_order(self, new_order: List[int], silent: bool = False) -> bool:
        """设置列顺序
        
        Args:
            new_order: 新的列顺序
            silent: 如果为True，则不发布事件（用于避免递归）
        """
        if self._data_manager.set_column_order(new_order, silent=silent):
            self.refresh_data()
            return True
        return False
    
    def get_marked_columns(self) -> Set[int]:
        """获取标记的列"""
        return self._data_manager.get_marked_columns()
    
    def set_marked_columns(self, marked_columns: Set[int]) -> bool:
        """设置标记的列"""
        # 检查新旧标记是否相同，如果相同则不执行任何操作
        old_marked = self._data_manager.get_marked_columns()
        if old_marked == marked_columns:
            return False
            
        if self._data_manager.set_marked_columns(marked_columns):
            self.refresh_data()
            return True
        return False
    
    def add_row(self, row_data: List[str]) -> bool:
        """添加行"""
        if self._data_manager.add_row(row_data):
            # 使用正确的行插入通知
            new_row = self.rowCount() - 1
            self.beginInsertRows(QModelIndex(), new_row, new_row)
            self.endInsertRows()
            return True
        return False
    
    def insert_row(self, position: int, row_data: List[str]) -> bool:
        """在指定位置插入行"""
        if self._data_manager.insert_row(position, row_data):
            # 使用正确的行插入通知
            self.beginInsertRows(QModelIndex(), position, position)
            self.endInsertRows()
            return True
        return False
    
    def remove_row(self, row: int) -> bool:
        """删除行"""
        if self._data_manager.remove_row(row):
            # 使用正确的行删除通知
            self.beginRemoveRows(QModelIndex(), row, row)
            self.endRemoveRows()
            return True
        return False
    
    def add_column(self, header: str, default_value: str = "") -> bool:
        """添加列（在末尾）"""
        if self._data_manager.add_column(header, default_value):
            self.refresh_data()
            return True
        return False
    
    def insert_column(self, position: int, header: str, default_value: str = "") -> bool:
        """在指定位置插入列"""
        if self._data_manager.insert_column(position, header, default_value):
            self.refresh_data()
            return True
        return False
    
    def remove_column(self, col: int) -> bool:
        """删除列"""
        if self._data_manager.remove_column(col):
            self.refresh_data()
            return True
        return False
    
    def is_cell_modified(self, row: int, col: int) -> bool:
        """检查单元格是否被修改"""
        column_order = self._data_manager.get_column_order()
        if col < len(column_order):
            actual_col = column_order[col]
        else:
            actual_col = col
        return self._data_manager.is_cell_modified(row, actual_col)
    
    def is_row_added(self, row: int) -> bool:
        """检查行是否被新增"""
        return self._data_manager.is_row_added(row)
    
    def is_row_deleted(self, row: int) -> bool:
        """检查行是否被删除"""
        return self._data_manager.is_row_deleted(row)
    
    def is_row_disabled(self, row: int) -> bool:
        """检查行是否被禁用"""
        return self._data_manager.is_row_disabled(row)
    
    def disable_row(self, row: int) -> bool:
        """禁用行"""
        if self._data_manager.disable_row(row):
            # 通知视图该行的数据已改变
            self._notify_row_changed(row)
            return True
        return False
    
    def enable_row(self, row: int) -> bool:
        """启用行"""
        if self._data_manager.enable_row(row):
            # 通知视图该行的数据已改变
            self._notify_row_changed(row)
            return True
        return False
    
    def disable_rows(self, rows: List[int]) -> bool:
        """批量禁用行"""
        if self._data_manager.disable_rows(rows):
            # 通知视图这些行的数据已改变
            for row in rows:
                self._notify_row_changed(row)
            return True
        return False
    
    def enable_rows(self, rows: List[int]) -> bool:
        """批量启用行"""
        if self._data_manager.enable_rows(rows):
            # 通知视图这些行的数据已改变
            for row in rows:
                self._notify_row_changed(row)
            return True
        return False
    
    def _notify_row_changed(self, row: int):
        """通知视图行数据已改变"""
        # 获取该行的所有列索引
        if self._column_range:
            # 如果有列范围限制，只通知显示的列
            for col in range(len(self._column_range)):
                index = self.index(row, col)
                if index.isValid():
                    self.dataChanged.emit(index, index)
        else:
            # 如果没有列范围限制，通知所有列
            for col in range(self.columnCount()):
                index = self.index(row, col)
                if index.isValid():
                    self.dataChanged.emit(index, index)
    
    def get_disabled_rows(self) -> Set[int]:
        """获取所有禁用的行"""
        return self._data_manager.get_disabled_rows()
    
    def get_modified_cells(self):
        """获取所有修改过的单元格"""
        return self._data_manager.get_modified_cells()
    
    def set_column_range(self, column_range: List[int]):
        """设置显示的列范围"""
        self._column_range = column_range
        # 不调用refresh_data()，因为它可能导致问题
        # 只通知视图列数发生了变化
        self.beginResetModel()
        self.endResetModel()
        
    def get_column_range(self) -> List[int]:
        """获取显示的列范围"""
        return self._column_range.copy()
        
    def clear_modification_flags(self):
        """清除修改标记"""
        self._data_manager.clear_modification_flags()
        self.refresh_data()
